package com.example.springboot2.service;

import com.example.springboot2.common.PageResult;
import com.example.springboot2.entity.Goods;
import com.example.springboot2.entity.Merchant;
import com.example.springboot2.exception.BusinessException;
import com.example.springboot2.repository.GoodsRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import jakarta.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;

/**
 * 商品服务类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class GoodsService {

    private final GoodsRepository goodsRepository;
    private final MerchantService merchantService;

    /**
     * 根据ID查找商品
     */
    public Goods findById(Long id) {
        return goodsRepository.findById(id)
                .orElseThrow(() -> new BusinessException("商品不存在"));
    }

    /**
     * 分页查询商品列表
     */
    public PageResult<Goods> getGoodsList(Long userId, Integer current, Integer size, 
                                          String name, String status, Long categoryId) {
        Merchant merchant = merchantService.getMerchantInfo(userId);
        
        Pageable pageable = PageRequest.of(current - 1, size, 
                Sort.by(Sort.Direction.DESC, "createdTime"));
        
        Specification<Goods> spec = (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            
            // 商家条件
            predicates.add(criteriaBuilder.equal(root.get("merchant"), merchant));
            
            // 商品名称模糊查询
            if (StringUtils.hasText(name)) {
                predicates.add(criteriaBuilder.like(root.get("name"), "%" + name + "%"));
            }
            
            // 状态查询
            if (StringUtils.hasText(status)) {
                predicates.add(criteriaBuilder.equal(root.get("status"), Goods.GoodsStatus.valueOf(status)));
            }
            
            // 分类查询
            if (categoryId != null) {
                predicates.add(criteriaBuilder.equal(root.get("category").get("id"), categoryId));
            }
            
            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        };
        
        Page<Goods> page = goodsRepository.findAll(spec, pageable);
        return PageResult.of(page);
    }

    /**
     * 获取商品详情
     */
    public Goods getGoodsDetail(Long userId, Long goodsId) {
        Merchant merchant = merchantService.getMerchantInfo(userId);
        Goods goods = findById(goodsId);
        
        // 验证商品是否属于当前商家
        if (!goods.getMerchant().getId().equals(merchant.getId())) {
            throw new BusinessException("无权访问该商品");
        }
        
        return goods;
    }

    /**
     * 创建商品
     */
    @Transactional
    public Goods createGoods(Long userId, Goods goods) {
        Merchant merchant = merchantService.getMerchantInfo(userId);
        goods.setMerchant(merchant);
        
        Goods savedGoods = goodsRepository.save(goods);
        log.info("商家创建商品: {} - {}", merchant.getShopName(), goods.getName());
        return savedGoods;
    }

    /**
     * 更新商品
     */
    @Transactional
    public Goods updateGoods(Long userId, Long goodsId, Goods goodsInfo) {
        Merchant merchant = merchantService.getMerchantInfo(userId);
        Goods existingGoods = findById(goodsId);
        
        // 验证商品是否属于当前商家
        if (!existingGoods.getMerchant().getId().equals(merchant.getId())) {
            throw new BusinessException("无权修改该商品");
        }
        
        // 更新商品信息
        existingGoods.setName(goodsInfo.getName());
        existingGoods.setDescription(goodsInfo.getDescription());
        existingGoods.setMainImage(goodsInfo.getMainImage());
        existingGoods.setImages(goodsInfo.getImages());
        existingGoods.setPrice(goodsInfo.getPrice());
        existingGoods.setOriginalPrice(goodsInfo.getOriginalPrice());
        existingGoods.setCostPrice(goodsInfo.getCostPrice());
        existingGoods.setStock(goodsInfo.getStock());
        existingGoods.setMinStock(goodsInfo.getMinStock());
        existingGoods.setWeight(goodsInfo.getWeight());
        existingGoods.setUnit(goodsInfo.getUnit());
        existingGoods.setType(goodsInfo.getType());
        existingGoods.setCategory(goodsInfo.getCategory());
        existingGoods.setTags(goodsInfo.getTags());
        existingGoods.setSeoTitle(goodsInfo.getSeoTitle());
        existingGoods.setSeoKeywords(goodsInfo.getSeoKeywords());
        existingGoods.setSeoDescription(goodsInfo.getSeoDescription());
        
        Goods savedGoods = goodsRepository.save(existingGoods);
        log.info("商家更新商品: {} - {}", merchant.getShopName(), goodsInfo.getName());
        return savedGoods;
    }

    /**
     * 删除商品
     */
    @Transactional
    public void deleteGoods(Long userId, Long goodsId) {
        Merchant merchant = merchantService.getMerchantInfo(userId);
        Goods goods = findById(goodsId);
        
        // 验证商品是否属于当前商家
        if (!goods.getMerchant().getId().equals(merchant.getId())) {
            throw new BusinessException("无权删除该商品");
        }
        
        // 软删除：设置状态为已删除
        goods.setStatus(Goods.GoodsStatus.DELETED);
        goodsRepository.save(goods);
        
        log.info("商家删除商品: {} - {}", merchant.getShopName(), goods.getName());
    }

    /**
     * 批量删除商品
     */
    @Transactional
    public void batchDeleteGoods(Long userId, List<Long> goodsIds) {
        Merchant merchant = merchantService.getMerchantInfo(userId);
        
        for (Long goodsId : goodsIds) {
            deleteGoods(userId, goodsId);
        }
        
        log.info("商家批量删除商品: {} - 数量: {}", merchant.getShopName(), goodsIds.size());
    }

    /**
     * 更新商品状态
     */
    @Transactional
    public void updateGoodsStatus(Long userId, Long goodsId, Goods.GoodsStatus status) {
        Merchant merchant = merchantService.getMerchantInfo(userId);
        Goods goods = findById(goodsId);
        
        // 验证商品是否属于当前商家
        if (!goods.getMerchant().getId().equals(merchant.getId())) {
            throw new BusinessException("无权修改该商品状态");
        }
        
        goods.setStatus(status);
        goodsRepository.save(goods);
        
        log.info("商家更新商品状态: {} - {} - {}", merchant.getShopName(), goods.getName(), status);
    }

    /**
     * 批量更新商品状态
     */
    @Transactional
    public void batchUpdateGoodsStatus(Long userId, List<Long> goodsIds, Goods.GoodsStatus status) {
        Merchant merchant = merchantService.getMerchantInfo(userId);
        
        for (Long goodsId : goodsIds) {
            updateGoodsStatus(userId, goodsId, status);
        }
        
        log.info("商家批量更新商品状态: {} - 数量: {} - 状态: {}", 
                merchant.getShopName(), goodsIds.size(), status);
    }

    /**
     * 获取热销商品
     */
    public List<Goods> getHotGoods(Long userId, Integer limit) {
        Merchant merchant = merchantService.getMerchantInfo(userId);
        Pageable pageable = PageRequest.of(0, limit != null ? limit : 10);
        return goodsRepository.findHotGoodsByMerchant(merchant, pageable);
    }

    /**
     * 获取商品统计数据
     */
    public GoodsStats getGoodsStats(Long userId) {
        Merchant merchant = merchantService.getMerchantInfo(userId);
        
        long totalCount = goodsRepository.countByMerchant(merchant);
        long onSaleCount = goodsRepository.countByMerchantAndStatus(merchant, Goods.GoodsStatus.ON_SALE);
        long offSaleCount = goodsRepository.countByMerchantAndStatus(merchant, Goods.GoodsStatus.OFF_SALE);
        long soldOutCount = goodsRepository.countByMerchantAndStatus(merchant, Goods.GoodsStatus.SOLD_OUT);
        
        return GoodsStats.builder()
                .totalCount(totalCount)
                .onSaleCount(onSaleCount)
                .offSaleCount(offSaleCount)
                .soldOutCount(soldOutCount)
                .build();
    }

    /**
     * 商品统计数据DTO
     */
    @lombok.Data
    @lombok.Builder
    public static class GoodsStats {
        private Long totalCount;
        private Long onSaleCount;
        private Long offSaleCount;
        private Long soldOutCount;
    }
}
